﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Drawing;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Security.Principal;
using System.IO.Compression;

namespace VIID
{
    public class Utils
    {
        public static HttpContent content(string content)
        {
            HttpContent result = new StringContent(content,Encoding.UTF8, "application/VIID+JSON");
            return result;
        }
        /// <summary>
        /// 获取Unix时间戳
        /// </summary>
        /// <returns></returns>
        public static long GetTimeStamp(DateTime dateTime)
        {
            TimeSpan ts = dateTime - new DateTime(1970, 1, 1, 0, 0, 0);
            return (long)ts.TotalSeconds;
        }
        /// <summary>
        /// 13位时间戳转 日期格式 1652338858000 -> 2022-05-12 03:00:58
        /// </summary>
        /// <param name="timestamp"></param>
        /// <returns></returns>
        public static DateTime GetDateTime(long timestamp)
        {
            timestamp = timestamp * 10000000;
            long time_tricks = new DateTime(1970, 1, 1, 0, 0, 0).Ticks + timestamp;//日志日期刻度
            DateTime dt = new DateTime(time_tricks);//转化为DateTime
            return dt;
        }
        public static string base64(string source, Encoding encodeType)
        {
            byte[] result = encodeType.GetBytes(source);
            return Convert.ToBase64String(result);
        }
        public static string base64(byte[] result)
        {
            return Convert.ToBase64String(result);
        }

        public class Stream
        {
            public static string read(global::System.IO.Stream stream)
            {
                using (var reader = new StreamReader(stream))
                {
                    return reader.ReadToEndAsync().Result;
                }
            }
        }
        public class Files
        {
            public static byte[] PtrToBytes(IntPtr pBuffer, int iLen)
            {
                //int iLen = (int)struITSPlateResult.struPicInfo[i].dwDataLen;
                byte[] buffer = new byte[iLen];
                Marshal.Copy(pBuffer, buffer, 0, iLen);
                return buffer;
            }

            public static void write(string filePath, byte[] buffer)
            {
                using (FileStream fs = new FileStream(filePath, FileMode.Create))
                {
                    fs.Write(buffer, 0, buffer.Length);
                    fs.Close();
                }
            }

            public static Dictionary<string, string> loadDictionary(XmlDocument xmldoc, string xpath)
            {
                Dictionary<string, string> result = new Dictionary<string, string>();
                XmlNodeList xnl = xmldoc.SelectNodes(xpath);
                if (xnl.Count > 0)//有消息
                {
                    foreach (XmlNode x in xnl)
                    {
                        result.Add(x.Attributes["code"].Value, x.Attributes["name"].Value);
                        Console.WriteLine(string.Format("字段:K={0};V={1}", x.Attributes["code"].Value, x.Attributes["value"].Value));
                    }
                }
                return result;
            }
        }
        public class RFC2617
        {
            public class UserInfo
            {
                public string username { get; set; }
                public string password { get; set; }
            }

            public static bool decode(string authHeader,string method,string realm, UserInfo user)
            {
                if (user == null)
                    return false;
                string username = GetDigestHeaderAttribute("username", authHeader);
                string uri = GetDigestHeaderAttribute("uri", authHeader);
                var nonce = GetDigestHeaderAttribute("nonce", authHeader);
                var nc = GetDigestHeaderAttribute("nc", authHeader);
                var cnonce = GetDigestHeaderAttribute("cnonce", authHeader);
                var qop = GetDigestHeaderAttribute("qop", authHeader);
                var response = GetDigestHeaderAttribute("response", authHeader);

                var _hash1 = md5(string.Format("{0}:{1}:{2}", user.username, realm, user.password));
                var _hash2 = md5(string.Format("{0}:{1}", method, uri));
                var _valid_response = md5(string.Format("{0}:{1}:{2}:{3}:{4}:{5}", _hash1, nonce, nc, cnonce, qop, _hash2));
                return (response == _valid_response);
            }
            /// <summary>
            /// Post 请求(摘要认证(digest authentication))
            /// </summary>
            /// <param name="url">请求地址</param>
            /// <param name="postData">请求数据</param>
            /// <param name="urlroute">接口的路由地址</param>
            /// <param name="username">用户名</param>
            /// <param name="username">密码</param>
            /// <returns></returns>
            public static string encode(string authHeader, string username, string password, string method, string urlroute)
            {
                string realm = GetDigestHeaderAttribute("realm", authHeader);
                string nonce = GetDigestHeaderAttribute("nonce", authHeader);
                string qop = GetDigestHeaderAttribute("qop", authHeader);
                string opaque = GetDigestHeaderAttribute("opaque", authHeader);
                //nc、cnonce是客户端自动生成的值
                string nc = DateTime.Now.ToString("yyMMddHHmmss");
                string cnonce = Guid.NewGuid().ToString().Replace("-", null);

                string _hash1 = md5(string.Format("{0}:{1}:{2}", username, realm, password));
                string _hash2 = md5(string.Format("{0}:{1}", method, urlroute));
                string _valid_response = md5(string.Format("{0}:{1}:{2}:{3}:{4}:{5}", _hash1, nonce, nc, cnonce, qop, _hash2));

                return string.Format("username=\"{0}\", realm=\"{1}\", qop=\"{2}\", algorithm=\"MD5\", uri=\"{3}\", nonce=\"{4}\", nc={5}, cnonce=\"{6}\", opaque=\"{7}=\", response=\"{8}\"",
                    username, realm, qop, urlroute, nonce, nc, cnonce, opaque, _valid_response
                    );
            }
            /// <summary>
            /// MD5　32位加密
            /// </summary>
            /// <param name="str"></param>
            /// <returns></returns>
            private static string md5(string str)
            {
                //MD5 md5 = new MD5CryptoServiceProvider();
                var md5 =  MD5.Create();//MD5.Create();
                byte[] bytes = Encoding.UTF8.GetBytes(str);
                bytes = md5.ComputeHash(bytes);
                md5.Clear();

                var ss = global::System.BitConverter.ToString(bytes);
                
                return ss.Replace("-","").ToLower();
            }

            private static string GetDigestHeaderAttribute(string attributeName, string digestAuthHeader)
            {
                if (string.IsNullOrEmpty(digestAuthHeader))
                    return null;
                var regHeader = new Regex(string.Format(@"{0}=""([^""]*)""", attributeName));
                var matchHeader = regHeader.Match(digestAuthHeader);
                if (matchHeader.Success)
                    return matchHeader.Groups[1].Value;
                return null;
                //throw new ApplicationException(string.Format("Header {0} not found", attributeName));
            }
        }
    }
}
